#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <pthread.h>
#include <semaphore.h>

// 创建四个线程，设计关于信号量的同步机制
sem_t sem_This, sem_is, sem_Jinan, sem_University;
pthread_mutex_t sem_mutex = PTHREAD_MUTEX_INITIALIZER;

// 对sem进行P操作，占用一个信号量
void P_sem(sem_t& sem) {
    sem_wait(&sem);
}

// 释放一个信号量，信号量加加
void V_sem(sem_t& sem) {
    sem_post(&sem);
}


void* PrintThis(void* args) {
    int cnt = 20;
    while (cnt--) {
        P_sem(sem_This);
        pthread_mutex_lock(&sem_mutex);
        std::cout << "This ";
        pthread_mutex_unlock(&sem_mutex);
        V_sem(sem_is);
    }
    return nullptr;
}

void* Printis(void* args) {
    int cnt = 20;
    while (cnt--) {
        P_sem(sem_is);
        pthread_mutex_lock(&sem_mutex);
        std::cout << "is ";
        pthread_mutex_unlock(&sem_mutex);
        V_sem(sem_Jinan); 
    }
    return nullptr; 
}

void* PrintJinan(void* args) {
    int cnt = 20;
    while (cnt--) {
        P_sem(sem_Jinan);
        pthread_mutex_lock(&sem_mutex);
        std::cout << "Jinan ";
        pthread_mutex_unlock(&sem_mutex);
        V_sem(sem_University);
    }
     
    return nullptr;   
}

void* PrintUniversity(void* args) {
    int cnt = 20;
    while (cnt--) {
        P_sem(sem_University);
        pthread_mutex_lock(&sem_mutex);
        std::cout << "University! --> " << 20 - cnt << "\n";
        pthread_mutex_unlock(&sem_mutex);
        V_sem(sem_This);  
    }
  
    return nullptr;
}

int main() {
    sem_init(&sem_This, 0, 1);
    sem_init(&sem_is, 0, 0);
    sem_init(&sem_Jinan, 0, 0);
    sem_init(&sem_University, 0, 0);
    pthread_t t1, t2, t3, t4;
    pthread_create(&t1, nullptr, PrintThis, nullptr);
    pthread_create(&t2, nullptr, Printis, nullptr);
    pthread_create(&t3, nullptr, PrintJinan, nullptr);
    pthread_create(&t4, nullptr, PrintUniversity, nullptr);


    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);
    pthread_join(t4, nullptr);

    sem_destroy(&sem_This);
    sem_destroy(&sem_is);
    sem_destroy(&sem_University);
    sem_destroy(&sem_Jinan);
    return 0;
}